package wator.model.agents;

import java.util.HashMap;
import java.util.Map;

import wator.model.Agent;
import wator.model.DrawingStrategy;
import wator.model.IntegerVector;
import wator.model.MovementStrategy;
import wator.model.Neighborhood;
import wator.model.NoDrawingStrategy;
import wator.model.strategies.NoMovementStrategy;

/**
 * This implementation can be used to model big fishes, that give more energy
 * to the predators. Note that the energy of the individuals is parameterized.
 * 
 * @see #setSpeciesParameter(String, int)
 */
public class BigFishAgent extends FishAgent {

	protected static int breedTime = 20;
	protected static MovementStrategy movementStrategy = 
			new NoMovementStrategy();
	private static DrawingStrategy drawingStrategy = 
			new NoDrawingStrategy();
	protected static int energy = 80;

	/**
	 * This constructor creates a big fish agent and takes the position and
	 * direction vectors from another agent instance.
	 *  
	 * @param agent the agent from which position and direction vectors
	 * 			are taken (not copied)
	 */
	public BigFishAgent(Agent agent) {
		super(agent);
	}
	
	/* (non-Javadoc)
	 * @see wator.model.agents.FishAgent#getEnergy()
	 */
	@Override
	public int getEnergy() {
		return energy;
	}
	
	/* (non-Javadoc)
	 * @see wator.model.agents.FishAgent#move(wator.model.Neighborhood)
	 */
	@Override
	public IntegerVector move(Neighborhood neighborhood) {
		age++;
		return movementStrategy.apply(this, neighborhood);
	}

	/* (non-Javadoc)
	 * @see wator.model.agents.FishAgent#breed(wator.model.Neighborhood)
	 */
	@Override
	public Agent breed(Neighborhood neighborhood) {
		return (age % breedTime == 0) ? new BigFishAgent(this) : null;
	}
	
	/**
	 * The parameter of this species are breedTime and energy.
	 * {@inheritDoc}
	 */
	@Override
	public void setSpeciesParameter(String key, int value) {
		if (key.equals("Breed Time")) {
			breedTime = value;
		} else if (key.equals("Energy")) {
			energy = value;
		}
	}

	/**
	 * The parameter of this species are breedTime and energy.
	 * {@inheritDoc}
	 */
	@Override
	public Map<String, Integer> getSpeciesParameters() {
		HashMap<String, Integer> params = new HashMap<String, Integer>();
		params.put("Breed Time", breedTime);
		params.put("Energy", energy);
		return params;
	}

	/* (non-Javadoc)
	 * @see wator.model.Agent#getMovementStrategy()
	 */
	@Override
	public MovementStrategy getMovementStrategy() {
		return movementStrategy;
	}

	/* (non-Javadoc)
	 * @see wator.model.Agent#setMovementStrategy(wator.model.MovementStrategy)
	 */
	@Override
	public void setMovementStrategy(MovementStrategy strategy) {
		movementStrategy = strategy;
	}
	
	/* (non-Javadoc)
	 * @see wator.model.Agent#setDrawingStrategy(wator.model.DrawingStrategy)
	 */
	@Override
	public void setDrawingStrategy(DrawingStrategy strategy) {
		drawingStrategy = strategy;
	}

	/* (non-Javadoc)
	 * @see wator.model.Agent#draw()
	 */
	@Override
	public void draw() {
		drawingStrategy.draw(this);
	}
	
	/* (non-Javadoc)
	 * @see wator.model.Agent#clone()
	 */
	@Override
	protected Object clone() {
		return new BigFishAgent(this);
	}
	
	/* (non-Javadoc)
	 * @see wator.model.Agent#getSpeciesName()
	 */
	@Override
	public String getSpeciesName() {
		return "Big Fish";
	}
}
